- 由于Java中的抽象类不能被实例化,所以我们不能注册bean,但如果在注册该bean时指定属性abstract为true,则该bean被声明为抽象bean,它不会被实例化,但是其属性可以注入到其他bean了。
- 抽象bean甚至不必映射到任何类。
- 抽象bean的一个好处是可以做模板,比如,有两个类含有相同的几个属性,那么在xml配置文件中,我们可能要通过两次重复的操作来为它们注入这些属性,定义抽象bean则很好地解决了这个问题。
//两个有相同属性的类(不用声明父类)
public class FooDao {
private DataSource dataSource;
private SomeHelper someHelper;
private FooHelper fooHelper;
//setters
}
public class BarDao {
private DataSource dataSource;
private SomeHelper someHelper;
private BarHelper barHelper;
//setters
}
//xml定义抽象bean(并不会实例化这个bean)
<bean id="dao" abstract="true"> <!--实际根本没有这个类-->
<property name="dataSource" ref="dataSource"/>
<property name="someHelper" ref="someHelper"/>
</bean>
<!--指定parent为dao,则只需要再注入自己特别的属性即可-->
<bean id="fooDao" class="FooDao" parent="dao">
<property name="fooHelper" ref="fooHelper" />
</bean>
<bean id="barDao" class="BarDao" parent="dao">
<property name="barHelper" ref="barHelper" />
</bean>
- 不过,引入这两个类都能继承的抽象Dao类还可以节省类定义时的属性声明代码
//抽象Dao类
public abstract Dao {
protected DataSource dataSource;
protected SomeHelper someHelper;
//setters
}
//这两个类都来继承它
public class FooDao extends Dao {
private FooHelper fooHelper;
//setters
}
public class BarDao extends Dao {
private BarHelper barHelper;
//setters
}
xml配置文件不变
因为抽象bean不需要实例化,所以一般不指明class属性。
- 但其实抽象bean Dao也可以指定class属性,映射到某个类上面,当子bean FooDao未指明class属性时,Spring就会找到父bean Dao的class,并把子bean都实例化为Dao类实例,因此这里的Dao不能是抽象类。
- 也即是说,抽象bean的映射类不一定是抽象类,因为抽象bean的“抽象”本不是抽象类的意思,是我们望文生义了。
- 参考文章
- 代码实例:ideaProjects/shirochapter12/resources/spring-beans.xml